import install from "./install.js";
import { createMatcher } from "./create-matcher.js";
import HashHistory from "./history/hash.js";
import HTML5History from "./history/h5.js";
class VueRouter {
  constructor(options = {}) {
    // console.log(options);
    const routes = options.routes;
    this.mode = options.mode || "hash";

    // 给我个路径， 我就返回给你对应的记录 about ==> about
    // match 匹配方法
    // addRoutes 动态添加路由
    this.matcher = createMatcher(options.routes || []);

    // 根据模式需要初始化不同的路由系统 hash/history 底层实现不一样， 但是使用的方式是一样的
    // hash ==> hash.js ==> push
    // history ==> history.js ==> push
    // base
    // 每次的跳转  我需要获取当前的路由  this.$router.pathname
    switch (this.mode) {
      case "hash": // location hash
        this.history = new HashHistory(this);
        break;
      case "history": // pushState
        this.history = new HTML5History(this);
        break;
    }
    this.beforeHooks = [];
  }
  push(location) {
    // 跳转页面
    this.history.transitionTo(location, () => {
      // 后续需要改进，还要使用pushState
      // window.location.hash = location; // 更改hash值
      this.history.pushState(location);
    });
  }
  match(location) {
    return this.matcher.match(location);
  }
  init(app) {
    // console.log(app);
    const history = this.history; // 当前管理路由的
    // hash ==> hashchange      但是浏览器支持popState 就优先采用popstate
    // history ==> popState  性能高于hashchange 但是有兼容问题
    // 页面初始化完成后， 就需要先进行一次跳转

    // 跳转到某个路径
    const setupListener = () => {
      // 此事件的实现方式也不一样
      history.setupListener();
    };
    history.transitionTo(
      history.getCurrentLocation(), // 各自的获取路径的方法也不一样
      setupListener
    );

    history.listen((route) => {
      // 监听 监听如果current变化了， 就重新给_route赋值
      app._route = route;
    });
  }

  beforeEach(next) {
    // this.beforeHooks.push({ to, from, next });
    this.beforeHooks.push(next);
  }
}

VueRouter.install = install;

export default VueRouter;

// 路由变化 --> 匹配结果 --> 更新响应式 --> 触发重新渲染router-view
// 路由的钩子执行的思路和 koa --> express 等中间件的原理是一样的， 就是把所有的钩子组成一个数组，一次执行
